<template>
  <div class="app-container">
    <!-- 左侧历史记录栏 -->
    <aside class="sidebar history-sidebar" :style="{ width: historyWidth + 'px' }">
      <div class="sidebar-header">
        <h3>历史记录</h3>
        <button @click="showClearConfirm" class="clear-btn" title="清空对话">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
          </svg>
        </button>
      </div>
      
      <div class="history-list">
        <!-- 加载状态 -->
        <div v-if="isLoadingHistory" class="history-loading">
          <div class="loading-spinner"></div>
          <span>加载对话历史...</span>
        </div>
        
        <!-- 新建对话按钮 -->
        <button @click="createNewSession" class="new-chat-btn">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M12 5v14M5 12h14"/>
          </svg>
          新建对话
        </button>
        
        <!-- 对话列表 -->
        <div 
          v-for="(session, index) in chatSessions" 
          :key="index"
          :class="['history-item', { 
            active: currentSessionIndex === index,
            'current-session': currentSessionIndex === index 
          }]"
          @click="currentSessionIndex !== index && switchSession(index)"
        >
          <div class="history-title">{{ session.title || `对话 ${index + 1}` }}</div>
          <div class="history-time">{{ formatDate(session.lastTime) }}</div>
        </div>
      </div>
      
      <!-- 用户账号区域 -->
      <div class="user-account-section">
        <div class="user-info" @click="goToAuth" @contextmenu.prevent="showUserMenu">
          <div class="user-avatar">
            <div v-if="userInfo.isLoggedIn" class="avatar-image">
              {{ userInfo.avatar || userInfo.nickname?.charAt(0) || 'U' }}
            </div>
            <div v-else class="avatar-placeholder">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
                <circle cx="12" cy="7" r="4"/>
              </svg>
            </div>
          </div>
          <div class="user-details">
            <div class="user-nickname">{{ userInfo.isLoggedIn ? userInfo.nickname : '未登录' }}</div>
            <div class="user-status">{{ userInfo.isLoggedIn ? '已登录' : '点击登录' }}</div>
          </div>
        </div>
        
        <!-- 用户右键菜单 -->
        <div v-if="showUserContextMenu" class="user-context-menu" :style="userMenuStyle">
          <div class="menu-item" @click="logout">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>
              <polyline points="16,17 21,12 16,7"/>
              <line x1="21" y1="12" x2="9" y2="12"/>
            </svg>
            登出
          </div>
        </div>
      </div>
      
      <!-- 历史记录栏拖拽手柄 -->
      <div 
        class="resize-handle history-resize-handle"
        @mousedown="startResize('history')"
        title="拖拽调整宽度"
      ></div>
    </aside>

    <!-- 中间对话区域 -->
    <main class="chat-main">
      <div class="chat-header">
        <div class="header-left">
          <button @click="goHome" class="home-btn" title="返回首页">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
              <polyline points="9,22 9,12 15,12 15,22"/>
            </svg>
          </button>
          <h2>{{ currentSession?.title || '新对话' }}</h2>
        </div>
      </div>

      <div class="messages-container" ref="messagesContainer">
        <!-- 消息历史加载状态 -->
        <div v-if="isLoadingMessages" class="messages-loading">
          <div class="loading-spinner"></div>
          <span>加载消息历史...</span>
        </div>
        
        <!-- 消息列表 -->
        <div 
          v-else
          v-for="(message, index) in currentSession?.messages || []" 
          :key="index" 
          :class="['message', message.role]"
        >
          <div class="message-avatar">
            <div v-if="message.role === 'user'" class="user-avatar">👤</div>
            <div v-else class="ai-avatar">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
              </svg>
            </div>
          </div>
          <div class="message-content">
            <!-- 加载状态显示加载动画 -->
            <div v-if="message.isLoading" class="loading-dots">
              <span></span>
              <span></span>
              <span></span>
            </div>
            <!-- 正常内容显示 -->
            <div v-else class="message-text" v-html="formatMessage(message.content)"></div>
            <div class="message-time">{{ formatTime(message.timestamp) }}</div>
          </div>
        </div>
        
        <!-- 加载状态 - 只在没有AI消息时显示 -->
        <div v-if="isLoading && (!currentSession?.messages || currentSession.messages.filter(m => m.role === 'assistant').length === 0)" class="message assistant">
          <div class="message-avatar">
            <div class="ai-avatar">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
              </svg>
            </div>
          </div>
          <div class="message-content">
            <div class="loading-dots">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-container" :style="{ minHeight: chatHeight + 'px' }">
        <!-- 聊天框高度调整手柄 -->
        <div 
          class="resize-handle chat-resize-handle"
          @mousedown="startResize('chat')"
          title="拖拽调整高度"
        ></div>
        
        <div class="input-wrapper">
          <textarea
            v-model="inputMessage"
            @keydown.enter.prevent="sendMessage"
            @keydown.enter.shift.exact="newLine"
            :placeholder="selectedFilesCount > 0 ? `输入您的问题... (已选择 ${selectedFilesCount} 个文件，Enter发送，Shift+Enter换行)` : '输入您的问题... (Enter发送，Shift+Enter换行)'"
            class="message-input"
            :style="{ height: Math.max(24, chatHeight - 80) + 'px' }"
            :disabled="isLoading"
            ref="inputRef"
          ></textarea>
        </div>
        <button 
          @click="sendMessage" 
          class="send-btn"
          :disabled="!inputMessage.trim() || isLoading"
        >
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
          </svg>
        </button>
      </div>
    </main>

    <!-- 右侧文件区 -->
    <aside class="sidebar file-sidebar" :style="{ width: fileWidth + 'px' }">
      <div class="sidebar-header">
        <h3>文件区 {{ selectedFilesCount > 0 ? `(${selectedFilesCount})` : '' }}</h3>
        <div class="header-buttons">
          <button 
            v-if="selectedFilesCount > 0" 
            @click="clearFileSelection" 
            class="clear-selection-btn" 
            title="清除选中"
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
          <button @click="uploadFile" class="upload-btn" title="上传文件">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/>
            </svg>
          </button>
        </div>
      </div>
      
      <div class="file-list">
        <div 
          v-for="(file, index) in files" 
          :key="index"
          :class="['file-item', { selected: file.selected }]"
          @click="selectFile(file)"
        >
          <div class="file-checkbox" @click="toggleFileSelection(file)">
            <input 
              type="checkbox" 
              :checked="file.selected" 
              @change="toggleFileSelection(file)"
              class="checkbox-input"
              @click.stop
            />
          </div>
          <div class="file-icon">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14,2 14,8 20,8"/>
            </svg>
          </div>
          <div class="file-info">
            <div class="file-name">{{ file.name }}</div>
            <div class="file-size">{{ formatFileSize(file.size) }}</div>
          </div>
        </div>
        
        <div v-if="files.length === 0" class="empty-state">
          <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
            <polyline points="14,2 14,8 20,8"/>
          </svg>
          <p>暂无文件</p>
          <button @click="uploadFile" class="upload-file-btn">上传文件</button>
        </div>
      </div>
      
      <!-- 文件区拖拽手柄 -->
      <div 
        class="resize-handle file-resize-handle"
        @mousedown="startResize('file')"
        title="拖拽调整宽度"
      ></div>
    </aside>

    <!-- 确认弹窗 -->
    <div v-if="showModal" class="modal-overlay" @click="closeModal">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3>确认清空</h3>
          <button @click="closeModal" class="modal-close">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
        </div>
        <div class="modal-body">
          <div class="modal-icon">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
            </svg>
          </div>
          <p>确定要清空所有对话吗？</p>
          <p class="modal-warning">此操作不可撤销，所有对话记录将被永久删除。</p>
        </div>
        <div class="modal-footer">
          <button @click="closeModal" class="modal-btn cancel-btn">取消</button>
          <button @click="confirmClear" class="modal-btn confirm-btn">确认清空</button>
        </div>
      </div>
    </div>

    <!-- 文件预览弹窗 -->
    <div v-if="showFileModal" class="modal-overlay" @click="closeFileModal">
      <div class="modal-content file-modal" @click.stop>
        <div class="modal-header">
          <h3>文件预览</h3>
          <button @click="closeFileModal" class="modal-close">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
        </div>
        <div class="modal-body file-preview-body">
          <div class="file-info">
            <div class="file-icon">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
                <polyline points="14,2 14,8 20,8"/>
              </svg>
            </div>
            <div class="file-details">
              <h4>{{ selectedFile?.name }}</h4>
              <p>{{ formatFileSize(selectedFile?.size || 0) }}</p>
            </div>
          </div>
          <div class="file-content">
            <pre>{{ selectedFile?.content || '文件内容加载中...' }}</pre>
          </div>
        </div>
        <div class="modal-footer">
          <button @click="closeFileModal" class="modal-btn cancel-btn">关闭</button>
          <button @click="useFileInChat" class="modal-btn confirm-btn">在对话中使用</button>
        </div>
      </div>
    </div>


  </div>
</template>

<script setup lang="ts">
import { ref, nextTick, onMounted, watch, computed, onUnmounted, triggerRef } from 'vue'
import { useRouter } from 'vue-router'
import { api } from '@/utils/api'

// MathJax类型声明
declare global {
  interface Window {
    MathJax?: {
      typesetPromise?: () => Promise<void>
      tex?: {
        inlineMath?: string[][]
        displayMath?: string[][]
        processEscapes?: boolean
        processEnvironments?: boolean
      }
      options?: {
        ignoreHtmlClass?: string
        processHtmlClass?: string
      }
    }
    currentAbortController?: AbortController
  }
}

interface Message {
  role: 'user' | 'assistant'
  content: string
  timestamp: Date
  isLoading?: boolean // 添加可选的加载状态标记
}

interface ChatSession {
  id: string
  title: string
  messages: Message[]
  lastTime: Date
}

interface FileItem {
  id: string
  name: string
  size: number
  type: string
  content?: string
  selected?: boolean
}

// 用户信息
interface UserInfo {
  isLoggedIn: boolean
  username?: string
  nickname?: string
  avatar?: string
}



const router = useRouter()

const messages = ref<Message[]>([])
const inputMessage = ref('')
const isLoading = ref(false)
const messagesContainer = ref<HTMLElement>()
const inputRef = ref<HTMLTextAreaElement>()

// 侧边栏宽度管理
const historyWidth = ref(280)
const fileWidth = ref(280)
const chatHeight = ref(120)
const isResizing = ref(false)
const resizeType = ref<'history' | 'file' | 'chat' | null>(null)

// 聊天会话管理
const chatSessions = ref<ChatSession[]>([])
const currentSessionIndex = ref(0)

// 新增：标记新创建的会话，用于调用create_conversation接口
const newSessionIds = ref<Set<string>>(new Set())

// 新增：加载状态
const isLoadingHistory = ref(false)
const isLoadingMessages = ref(false)
const isStreaming = ref(false)

// 文件管理
const files = ref<FileItem[]>([])

// 弹窗状态
const showModal = ref(false)
const showFileModal = ref(false)
const selectedFile = ref<FileItem | null>(null)

// 用户相关状态
const userInfo = ref<UserInfo>({
  isLoggedIn: false
})

// 用户右键菜单状态
const showUserContextMenu = ref(false)
const userMenuX = ref(0)
const userMenuY = ref(0)

// 当前会话
const currentSession = computed(() => chatSessions.value[currentSessionIndex.value])

// 拖拽调整宽度相关方法
const startResize = (type: 'history' | 'file' | 'chat') => {
  isResizing.value = true
  resizeType.value = type
  document.addEventListener('mousemove', handleResize)
  document.addEventListener('mouseup', stopResize)
  
  // 根据拖拽类型设置不同的光标样式
  if (type === 'chat') {
    document.body.style.cursor = 'row-resize'
  } else {
    document.body.style.cursor = 'col-resize'
  }
  
  document.body.style.userSelect = 'none'
}

const handleResize = (e: MouseEvent) => {
  if (!isResizing.value) return
  
  const minWidth = 200
  const maxWidth = 500
  const minChatHeight = 80
  const maxChatHeight = 300
  
  if (resizeType.value === 'history') {
    const newWidth = Math.max(minWidth, Math.min(maxWidth, e.clientX))
    historyWidth.value = newWidth
  } else if (resizeType.value === 'file') {
    const newWidth = Math.max(minWidth, Math.min(maxWidth, window.innerWidth - e.clientX))
    fileWidth.value = newWidth
  } else if (resizeType.value === 'chat') {
    const newHeight = Math.max(minChatHeight, Math.min(maxChatHeight, window.innerHeight - e.clientY))
    chatHeight.value = newHeight
  }
}

const stopResize = () => {
  isResizing.value = false
  resizeType.value = null
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
  document.body.style.cursor = ''
  document.body.style.userSelect = ''
}

// 自动滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    }
  })
}

// 监听消息变化，自动滚动
watch(() => currentSession.value?.messages, scrollToBottom, { deep: true })

// 监听拖拽状态
watch(isResizing, (resizing) => {
  if (resizing) {
    document.body.classList.add('resizing')
    if (resizeType.value === 'chat') {
      document.body.classList.add('chat-resizing')
    }
  } else {
    document.body.classList.remove('resizing', 'chat-resizing')
  }
})

// 发送消息
const sendMessage = async () => {
  const message = inputMessage.value.trim()
  if (!message || isLoading.value) return

  // 获取选中的文件
  const selectedFiles = files.value.filter(file => file.selected)
  
  // 构建显示给用户的消息（只包含文件名）
  let displayMessage = message
  if (selectedFiles.length > 0) {
    // displayMessage += '\n\n--- 附加文件 ---\n'
    selectedFiles.forEach((file, index) => {
      displayMessage += `\n【文件 ${index + 1}: ${file.name}】\n`
    })
    //displayMessage += '--- 文件列表结束 ---\n'
  }
  
  // 构建发送给AI的完整消息（包含文件内容）
  let fullMessage = message
  if (selectedFiles.length > 0) {
    fullMessage += '\n\n--- 附加文件内容 ---\n'
    selectedFiles.forEach((file, index) => {
      fullMessage += `\n【文件 ${index + 1}: ${file.name}】\n`
      fullMessage += file.content || '文件内容为空'
      fullMessage += '\n'
    })
    fullMessage += '--- 文件内容结束 ---\n'
  }

  // 添加用户消息（显示版本）
  const userMessage: Message = {
    role: 'user',
    content: displayMessage,
    timestamp: new Date()
  }
  
  currentSession.value.messages.push(userMessage)
  
  // 更新会话标题（如果是第一条消息）
  if (currentSession.value.messages.length === 1) {
    currentSession.value.title = message.substring(0, 20) + (message.length > 20 ? '...' : '')
  }
  
  // 更新最后时间
  currentSession.value.lastTime = new Date()

  inputMessage.value = ''
  isLoading.value = true

  try {
    // 如果是新会话的第一条消息，先调用create_conversation接口
    if (newSessionIds.value.has(currentSession.value.id) && currentSession.value.messages.length === 1) {
      const result = await createConversation()
      // 如果后端返回了新的conversation_id，更新当前会话的ID
      if (result && result.data && result.data.conversation_id) {
        currentSession.value.id = result.data.conversation_id.toString()
      }
      
      // 调用成功后从新会话集合中移除
      newSessionIds.value.delete(currentSession.value.id)
    }
    
    // 调用create_message接口保存用户消息（保存显示版本）
    await createMessage('user', displayMessage)
    
    // 调用后端AI流式接口
    await callAIStreamAPI(fullMessage)
  } catch (error) {
    console.error('发送消息失败:', error)
    const errorMessage: Message = {
      role: 'assistant',
      content: '抱歉，我遇到了一些问题，请稍后再试。',
      timestamp: new Date()
    }
    currentSession.value.messages.push(errorMessage)
  } finally {
    isLoading.value = false
  }
}

// 获取对话历史列表
const fetchChatHistory = async () => {
  try {
    isLoadingHistory.value = true
    
    // 获取用户名
    const username = userInfo.value.username || 'asfgjkzxvbm'
    
    // 使用api工具类，会自动处理401错误并跳转到登录页
    const result = await api.get(`/api/ai/history?username=${encodeURIComponent(username)}`)
    
    // 检查API返回的错误
    if (!result.success) {
      throw new Error(result.message || '获取对话历史失败')
    }
    
    // 处理返回的对话列表数据
    if (result.success && result.data && result.data.conversations && Array.isArray(result.data.conversations)) {
      // 将后端数据转换为前端格式
      chatSessions.value = result.data.conversations.map((conv: any) => ({
        id: conv.id.toString(),
        title: conv.first_message || `对话 ${conv.id}`,
        messages: [], // 历史接口只返回对话列表，不包含具体消息
        lastTime: conv.datetime ? new Date(conv.datetime) : new Date()
      }))
      
      // 如果没有对话，创建一个默认的新对话
      if (chatSessions.value.length === 0) {
        createDefaultSession()
      } else {
        // 如果有对话，获取第一个对话的消息历史
        // 使用nextTick确保DOM更新后再获取消息历史
        nextTick(async () => {
          await fetchMessageHistory()
        })
      }
    } else {
      createDefaultSession()
    }
    
  } catch (error) {
    console.error('获取对话历史失败:', error)
    // 如果获取失败，创建一个默认的新对话
    createDefaultSession()
  } finally {
    isLoadingHistory.value = false
  }
}

// 创建默认会话
const createDefaultSession = () => {
  const defaultSession: ChatSession = {
    id: Date.now().toString(),
    title: '新对话',
    messages: [],
    lastTime: new Date()
  }
  chatSessions.value = [defaultSession]
  currentSessionIndex.value = 0
  
  // 标记这个新会话，等待第一条消息时调用create_conversation接口
  newSessionIds.value.add(defaultSession.id)
}

// 调用create_conversation接口
const createConversation = async () => {
  try {
    // 获取用户名
    const username = userInfo.value.username || 'asfgjkzxvbm'
    
    // 使用api工具类，会自动处理401错误并跳转到登录页
    const result = await api.get(`/api/ai/create_conversation?username=${encodeURIComponent(username)}`)
    
    return result
  } catch (error) {
    console.error('调用create_conversation接口失败:', error)
    throw error
  }
}

// 获取对话消息历史
const fetchMessageHistory = async () => {
  try {
    isLoadingMessages.value = true
    
    // 获取当前对话ID
    const conversationId = currentSession.value.id
    
    // 使用api工具类，会自动处理401错误并跳转到登录页
    const result = await api.get(`/api/ai/message_history?conversation_id=${conversationId}`)
    
    // 检查API返回的错误
    if (!result.success) {
      throw new Error(result.message || '获取消息历史失败')
    }
    
    // 处理返回的消息列表数据
    if (result.data && result.data.messages && Array.isArray(result.data.messages)) {
      // 将后端消息数据转换为前端格式
      const messages: Message[] = result.data.messages.map((msg: any) => ({
        role: msg.role,
        content: msg.content,
        timestamp: msg.datetime ? new Date(msg.datetime) : new Date() // 使用后端返回的时间戳
      }))
      
      // 更新当前会话的消息列表
      currentSession.value.messages = [...messages] // 使用展开运算符创建新数组
      
      // 强制触发响应式更新
      triggerRef(currentSession)
      
      // 等待DOM更新后重新渲染数学公式和格式化内容
      nextTick(() => {
        renderMath()
        
        // 检查是否有需要格式化的内容
        const hasFormattedContent = messages.some(msg => 
          msg.content.includes('## **') || 
          msg.content.includes('**') || 
          msg.content.includes('---') || 
          msg.content.includes('- ') ||
          /\\[\(\[].*?\\[\)\]]/.test(msg.content)
        )
        
        if (hasFormattedContent) {
          // 再次触发响应式更新以确保格式化内容正确显示
          triggerRef(currentSession)
        }
        
        // 消息历史加载完成后，滚动到底部
        setTimeout(() => {
          scrollToBottom()
        }, 100)
      })
    } else {
      currentSession.value.messages = []
    }
    
  } catch (error) {
    console.error('获取消息历史失败:', error)
    // 如果获取失败，清空消息列表
    currentSession.value.messages = []
  } finally {
    isLoadingMessages.value = false
  }
}

// 调用create_message接口
const createMessage = async (role: 'user' | 'assistant', content: string) => {
  try {
    // 获取当前对话ID并转换为整数
    const conversationId = parseInt(currentSession.value.id)
    
    // 检查conversation_id是否有效
    if (isNaN(conversationId)) {
      throw new Error(`无效的conversation_id: ${currentSession.value.id}`)
    }
    
    // 使用api工具类，会自动处理401错误并跳转到登录页
    const result = await api.post('/api/ai/create_message', {
      conversation_id: conversationId,
      role: role,
      content: content
    })
    
    return result
  } catch (error) {
    console.error('调用create_message接口失败:', error)
    throw error
  }
}

// 调用后端AI流式接口
const callAIStreamAPI = async (userMessage: string) => {
  // 创建AbortController用于中止请求
  const abortController = new AbortController()
  
  try {
    // 获取认证token
    const token = localStorage.getItem('authToken')
    
    // 立即创建AI消息，让气泡立即出现（显示加载状态）
    const aiMessage: Message = {
      role: 'assistant',
      content: '',
      timestamp: new Date(),
      isLoading: true // 添加加载状态标记
    }
    currentSession.value.messages.push(aiMessage)
    
    // 强制触发响应式更新，确保气泡立即显示
    triggerRef(currentSession)
    
    // 调用后端流式接口
    const response = await fetch('/api/ai/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(token && { 'Authorization': `Bearer ${token}` })
      },
      body: JSON.stringify({
        message: userMessage
      }),
      signal: abortController.signal // 添加中止信号
    })

    if (!response.ok) {
      // 处理401未授权
      if (response.status === 401) {
        localStorage.removeItem('authToken')
        localStorage.removeItem('userInfo')
        window.location.href = '/auth'
        throw new Error('登录已过期，请重新登录')
      }
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    // 检查响应类型
    const contentType = response.headers.get('content-type')
    if (!contentType || !contentType.includes('text/event-stream')) {
      // 响应类型不是预期的流式类型
    }

    // 获取响应流
    const reader = response.body?.getReader()
    if (!reader) {
      throw new Error('无法获取响应流')
    }
    
    // 将abortController暴露到全局，供其他函数使用
    window.currentAbortController = abortController

    const decoder = new TextDecoder()
    let buffer = ''
    let receivedChunks = 0
    let lastUpdateTime = Date.now()
    let lastRenderTime = Date.now()
    let pendingRender = false

    isStreaming.value = true

    while (true) {
      // 检查是否被中止
      if (abortController.signal.aborted) {
        break
      }
      
      // 检查当前会话是否还是发送消息时的会话
      if (!currentSession.value.messages.includes(aiMessage)) {
        break
      }
      
      const { done, value } = await reader.read()
      
      if (done) {
        break
      }
      
      // 解码数据
      const chunk = decoder.decode(value, { stream: true })
      buffer += chunk
      receivedChunks++
      
      // 处理完整的数据行
      const lines = buffer.split('\n')
      buffer = lines.pop() || '' // 保留不完整的行
      
      for (const line of lines) {
        if (line.trim() === '') continue // 跳过空行
        
        if (line.startsWith('data: ')) {
          const data = line.slice(6) // 移除 'data: ' 前缀
          
          if (data === '[DONE]') {
            // 流式响应结束
            currentSession.value.lastTime = new Date()
            
            // 保存AI消息到后端
            if (aiMessage && aiMessage.content && currentSession.value.messages.includes(aiMessage)) {
              // 确保移除加载状态
              aiMessage.isLoading = false
              try {
                await createMessage('assistant', aiMessage.content)
              } catch (error) {
                console.error('保存AI消息失败:', error)
              }
            }
            
            // 流式响应结束，进行最终的完整渲染
            isStreaming.value = false
            
            // 清理abortController
            window.currentAbortController = undefined
            
            // 强制触发响应式更新，重新格式化内容
            triggerRef(currentSession)
            
            setTimeout(() => {
              renderMath()
            }, 100)
            
            return
          }
          
          try {
            // 解析JSON数据
            const parsed = JSON.parse(data)
            if (parsed.choices && parsed.choices[0] && parsed.choices[0].delta && parsed.choices[0].delta.content) {
              const content = parsed.choices[0].delta.content
              
              // 检查当前会话是否还是发送消息时的会话
              if (!currentSession.value.messages.includes(aiMessage)) {
                return
              }
              
              if (aiMessage && aiMessage.content === '' && content) {
                // 第一次收到内容，移除加载状态
                aiMessage.isLoading = false
              }
              
              // 直接追加内容到AI消息，实时更新
              aiMessage.content += content
              
              // 记录更新频率
              const now = Date.now()
              if (now - lastUpdateTime > 1000) { // 每秒记录一次
                lastUpdateTime = now
              }
              
              // 优化渲染频率：只在特定条件下才进行完整渲染
              const shouldRender = now - lastRenderTime > 500 || // 每500ms渲染一次
                                 content.includes('\n') || // 换行时渲染
                                 content.includes('**') || // 包含格式化内容时渲染
                                 content.includes('---') || // 包含分割线时渲染
                                 content.includes('- ') // 包含列表时渲染
              
              if (shouldRender && !pendingRender) {
                pendingRender = true
                lastRenderTime = now
                
                // 强制触发响应式更新 - 确保Vue检测到变化
                triggerRef(currentSession)
                
                // 使用setTimeout异步渲染，避免阻塞流式数据接收
                setTimeout(async () => {
                  try {
                    // 立即触发DOM更新
                    await nextTick()
                  } finally {
                    pendingRender = false
                  }
                }, 0)
              } else {
                // 对于普通文本更新，只触发响应式更新，不进行复杂渲染
                triggerRef(currentSession)
              }
            }
          } catch (e) {
            // 解析流式数据失败
          }
        }
      }
    }
    
    // 更新最后时间
    currentSession.value.lastTime = new Date()
    
    // 如果流式响应异常结束，也要保存AI消息
    isStreaming.value = false
    
    // 清理abortController
    window.currentAbortController = undefined
    
    // 获取最后一条AI消息
    const lastMessage = currentSession.value.messages[currentSession.value.messages.length - 1]
    if (lastMessage && lastMessage.role === 'assistant' && lastMessage.content && currentSession.value.messages.includes(aiMessage)) {
      // 确保移除加载状态
      lastMessage.isLoading = false
      try {
        await createMessage('assistant', lastMessage.content)
      } catch (error) {
        console.error('保存AI消息失败（异常结束）:', error)
      }
    }
    
  } catch (error) {
    console.error('调用AI接口失败:', error)
    isStreaming.value = false
    
    // 清理abortController
    window.currentAbortController = undefined
    
    // 获取最后一条AI消息
    const lastMessage = currentSession.value.messages[currentSession.value.messages.length - 1]
    
    // 如果最后一条消息是AI消息且内容为空，设置为错误消息
    if (lastMessage && lastMessage.role === 'assistant' && lastMessage.content === '') {
      lastMessage.content = '抱歉，我遇到了一些问题，请稍后再试。'
      lastMessage.isLoading = false // 移除加载状态
      
      // 保存错误消息到后端
      try {
        await createMessage('assistant', lastMessage.content)
      } catch (saveError) {
        console.error('保存错误消息失败:', saveError)
      }
    } else if (!lastMessage || lastMessage.role !== 'assistant') {
      // 如果没有AI消息，添加错误消息
      const errorMessage: Message = {
        role: 'assistant',
        content: '抱歉，我遇到了一些问题，请稍后再试。',
        timestamp: new Date()
      }
      currentSession.value.messages.push(errorMessage)
      
      // 保存错误消息到后端
      try {
        await createMessage('assistant', errorMessage.content)
      } catch (saveError) {
        console.error('保存错误消息失败:', saveError)
      }
    }
  }
}

// 换行功能
const newLine = () => {
  inputMessage.value += '\n'
}

// 清空对话
const clearChat = async () => {
  try {
    // 获取用户名
    const username = userInfo.value.username || 'asfgjkzxvbm'
    
    // 使用api工具类，会自动处理401错误并跳转到登录页
    const result = await api.delete(`/api/ai/delete_conversations?username=${encodeURIComponent(username)}`)
    
    // 检查API返回的错误
    if (!result.success) {
      throw new Error(result.message || '删除对话失败')
    }
    
    // 删除成功后，立即调用后端创建新对话
    const createResult = await createConversation()
    
    let conversationId = Date.now().toString() // 默认ID
    
    // 如果后端返回了新的conversation_id，使用后端返回的ID
    if (createResult && createResult.data && createResult.data.conversation_id) {
      conversationId = createResult.data.conversation_id.toString()
    }
    
    // 创建新会话，使用后端返回的真实ID
    const newSession: ChatSession = {
      id: conversationId,
      title: '新对话',
      messages: [],
      lastTime: new Date()
    }
    chatSessions.value = [newSession]
    currentSessionIndex.value = 0
    
    // 清空新会话标记（因为已经创建了真实的后端对话）
    newSessionIds.value.clear()
    
    // 清空对话后滚动到底部
    nextTick(() => {
      scrollToBottom()
    })
    
  } catch (error) {
    console.error('删除对话失败:', error)
    // 即使删除失败，也清空本地对话并创建新对话
    try {
      // 尝试创建新对话
      const createResult = await createConversation()
      
      let conversationId = Date.now().toString() // 默认ID
      
      if (createResult && createResult.data && createResult.data.conversation_id) {
        conversationId = createResult.data.conversation_id.toString()
      }
      
      const newSession: ChatSession = {
        id: conversationId,
        title: '新对话',
        messages: [],
        lastTime: new Date()
      }
      chatSessions.value = [newSession]
      currentSessionIndex.value = 0
      newSessionIds.value.clear()
    } catch (createError) {
      console.error('创建新对话也失败:', createError)
      // 最后的备选方案：使用本地ID
      createDefaultSession()
    }
    
    nextTick(() => {
      scrollToBottom()
    })
  }
}

// 创建新会话
const createNewSession = async () => {
  // 检查是否已经存在空的新对话（包括标记为新会话的和标题为"新对话"的空对话）
  const existingEmptySessionIndex = chatSessions.value.findIndex(session => 
    session.messages.length === 0 && (
      newSessionIds.value.has(session.id) || 
      session.title === '新对话'
    )
  )
  
  if (existingEmptySessionIndex !== -1) {
    // 如果存在空的新对话，切换到该对话
    currentSessionIndex.value = existingEmptySessionIndex
    return
  }
  
  // 如果没有空的新对话，创建新的对话
  const newSession: ChatSession = {
    id: Date.now().toString(),
    title: '新对话',
    messages: [],
    lastTime: new Date()
  }
  chatSessions.value.unshift(newSession)
  currentSessionIndex.value = 0
  
  // 标记这个新会话，等待第一条消息时调用create_conversation接口
  newSessionIds.value.add(newSession.id)
  
  // 清空当前消息列表，因为新会话没有历史消息
  currentSession.value.messages = []
  
  // 新会话创建后滚动到底部
  nextTick(() => {
    scrollToBottom()
  })
}

// 切换会话
const switchSession = async (index: number) => {
  // 如果正在AI回复，中止当前请求并清理加载状态
  if (isLoading.value && window.currentAbortController) {
    window.currentAbortController.abort()
    window.currentAbortController = undefined
    isLoading.value = false
    isStreaming.value = false
    
    // 清理当前会话中的加载状态气泡
    const currentMessages = currentSession.value.messages
    const lastMessage = currentMessages[currentMessages.length - 1]
    if (lastMessage && lastMessage.role === 'assistant' && lastMessage.isLoading) {
      currentMessages.pop() // 移除加载状态的气泡
      triggerRef(currentSession) // 强制更新
    }
  }
  
  currentSessionIndex.value = index
  
  // 检查当前会话是否是临时ID的对话（需要先创建后端对话）
  const targetSession = chatSessions.value[index]
  if (newSessionIds.value.has(targetSession.id) && targetSession.messages.length === 0) {
    try {
      // 调用后端创建对话接口
      const result = await createConversation()
      
      // 如果后端返回了新的conversation_id，更新当前会话的ID
      if (result && result.data && result.data.conversation_id) {
        targetSession.id = result.data.conversation_id.toString()
      }
      
      // 从新会话集合中移除
      newSessionIds.value.delete(targetSession.id)
      
      // 由于是新创建的对话，没有历史消息，直接返回
      return
    } catch (error) {
      // 如果创建失败，仍然尝试获取消息历史（可能会失败，但至少尝试了）
    }
  }
  
  // 获取选中对话的消息历史
  await fetchMessageHistory()
}

// 上传文件
const uploadFile = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.txt'
  input.multiple = true
  input.onchange = (e) => {
    const target = e.target as HTMLInputElement
    if (target.files) {
      Array.from(target.files).forEach(file => {
        // 检查文件类型
        if (file.type !== 'text/plain' && !file.name.endsWith('.txt')) {
          alert('只能上传 .txt 文件')
          return
        }
        
        // 读取文件内容
        const reader = new FileReader()
        reader.onload = (e) => {
          const content = e.target?.result as string
          const fileItem: FileItem = {
            id: Date.now().toString() + Math.random(),
            name: file.name,
            size: file.size,
            type: file.type,
            content: content,
            selected: false
          }
          files.value.push(fileItem)
        }
        reader.readAsText(file)
      })
    }
  }
  input.click()
}

// 选择文件
const selectFile = (file: FileItem) => {
  selectedFile.value = file
  showFileModal.value = true
}

// 显示清空确认弹窗
const showClearConfirm = () => {
  showModal.value = true
}

// 关闭弹窗
const closeModal = () => {
  showModal.value = false
}

// 确认清空
const confirmClear = async () => {
  closeModal()
  await clearChat()
}

// 关闭文件预览弹窗
const closeFileModal = () => {
  showFileModal.value = false
  selectedFile.value = null
}

// 在对话中使用文件
const useFileInChat = () => {
  if (selectedFile.value?.content) {
    inputMessage.value = `请帮我分析以下文件内容：\n\n${selectedFile.value.content}`
    closeFileModal()
  }
}

// 防抖渲染数学公式
let renderMathTimeout: number | null = null
const renderMath = () => {
  // 清除之前的定时器
  if (renderMathTimeout) {
    clearTimeout(renderMathTimeout)
  }
  
  // 设置新的定时器，防抖处理
  renderMathTimeout = setTimeout(() => {
    nextTick(() => {
          // 检查MathJax是否已加载
    if (window.MathJax && window.MathJax.typesetPromise) {
      window.MathJax.typesetPromise().then(() => {
        // 数学公式渲染完成
      }).catch((error) => {
        // MathJax渲染失败
          // 如果渲染失败，尝试重新加载MathJax
          setTimeout(() => {
            loadMathJax().then(() => {
              setTimeout(renderMath, 100)
            })
          }, 1000)
        })
      } else {
        // 如果MathJax还没加载完成，尝试重新加载
        loadMathJax().then(() => {
          setTimeout(renderMath, 100)
        })
      }
    })
  }, 100) // 100ms防抖延迟
}

// 格式化消息内容（支持换行、标题和数学公式）
const formatMessage = (content: string) => {
  let formattedContent = content
  
  // 检查是否包含数学公式
  const hasMath = /\\[\(\[].*?\\[\)\]]/.test(content)
  
  // 处理大标题（## **content**格式）
  formattedContent = formattedContent.replace(/## \*\*(.+?)\*\*/g, '<h2 class="message-title-large">$1</h2>')
  
  // 再处理小标题（**content**格式）- 只加粗，不换行
  formattedContent = formattedContent.replace(/\*\*(.+?)\*\*/g, '<strong class="message-title-small">$1</strong>')
  
  // 处理普通的#开头的行（移除#号）
  formattedContent = formattedContent.replace(/^#+\s*(.+)$/gm, '$1')
  
  // 处理分割线（---）
  formattedContent = formattedContent.replace(/---/g, '<hr class="message-divider">')
  
  // 处理圆点列表（- 开头）- 使用更精确的正则表达式
  formattedContent = formattedContent.replace(/^- (.+)$/gm, '<li class="message-list-item">$1</li>')
  
  // 如果上面的正则表达式不工作，尝试更宽松的匹配
  formattedContent = formattedContent.replace(/^- (.+)/gm, '<li class="message-list-item">$1</li>')
  
  // 最后处理换行
  formattedContent = formattedContent.replace(/\n/g, '<br>')
  
  // 在流式更新时，保持数学公式的原始格式，避免闪烁
  if (hasMath && isStreaming.value) {
    // 将数学公式包装在span中，添加特殊类名，在流式更新时不渲染
    formattedContent = formattedContent.replace(/\\([\(\[].*?[\)\]])\\/g, '<span class="math-formula-raw">$1</span>')
  }
  
  // 处理Markdown风格的[文字](链接)
  formattedContent = formattedContent.replace(
    /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,
    '<a href="$2" target="_blank" rel="noopener noreferrer" class="message-link">$1</a>'
  )
  
  return formattedContent
}

// 格式化时间
const formatTime = (timestamp: Date) => {
  return timestamp.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 格式化日期
const formatDate = (timestamp: Date) => {
  const now = new Date()
  const diff = now.getTime() - timestamp.getTime()
  const days = Math.floor(diff / (1000 * 60 * 60 * 24))
  
  if (days === 0) {
    return '今天'
  } else if (days === 1) {
    return '昨天'
  } else if (days < 7) {
    return `${days}天前`
  } else {
    return timestamp.toLocaleDateString('zh-CN')
  }
}

// 格式化文件大小
const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}

// 返回首页
const goHome = () => {
  router.push('/')
}

// 切换文件选中状态
const toggleFileSelection = (file: FileItem) => {
  const index = files.value.findIndex(f => f.id === file.id)
  if (index !== -1) {
    files.value[index].selected = !files.value[index].selected
  }
}

// 清除文件选中状态
const clearFileSelection = () => {
  files.value.forEach((file, index) => {
    files.value[index].selected = false
  })
}

// 计算选中的文件数量
const selectedFilesCount = computed(() => files.value.filter(file => file.selected).length)

// 跳转到认证页面
const goToAuth = () => {
  router.push('/auth')
}

// 显示用户右键菜单
const showUserMenu = (event: MouseEvent) => {
  event.preventDefault()
  userMenuX.value = event.clientX
  userMenuY.value = event.clientY
  showUserContextMenu.value = true
  
  // 添加全局点击事件监听器来关闭菜单
  nextTick(() => {
    document.addEventListener('click', closeUserMenu, { once: true })
  })
}

// 关闭用户右键菜单
const closeUserMenu = () => {
  showUserContextMenu.value = false
}

// 登出
const logout = () => {
  // 清空用户信息
  userInfo.value = {
    isLoggedIn: false
  }
  // 清空localStorage
  localStorage.removeItem('userInfo')
  // 跳转到首页
  router.push('/')
  closeUserMenu()
}

// 用户右键菜单样式
const userMenuStyle = computed(() => {
  const menuWidth = 140
  const menuHeight = 60
  let left = userMenuX.value
  let top = userMenuY.value
  
  // 确保菜单不会超出屏幕边界
  if (left + menuWidth > window.innerWidth) {
    left = window.innerWidth - menuWidth - 10
  }
  if (top + menuHeight > window.innerHeight) {
    top = window.innerHeight - menuHeight - 10
  }
  
  // 确保菜单不会超出屏幕左边界和上边界
  if (left < 10) {
    left = 10
  }
  if (top < 10) {
    top = 10
  }
  
  return {
    left: `${left}px`,
    top: `${top}px`
  }
})

// 动态加载MathJax
const loadMathJax = () => {
  return new Promise<void>((resolve) => {
    // 检查是否已经加载
    if (window.MathJax && window.MathJax.typesetPromise) {
      resolve()
      return
    }

    // 先配置MathJax（必须在加载前配置）
    window.MathJax = {
      tex: {
        inlineMath: [['\\(', '\\)']],
        displayMath: [['\\[', '\\]']],
        processEscapes: true,
        processEnvironments: true
      },
      options: {
        ignoreHtmlClass: 'tex2jax_ignore',
        processHtmlClass: 'tex2jax_process'
      }
    }

    // 直接加载MathJax
    const mathjaxScript = document.createElement('script')
    mathjaxScript.id = 'MathJax-script'
    mathjaxScript.async = true
    mathjaxScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js'
    
    mathjaxScript.onload = () => {
      // 等待MathJax完全初始化
      const checkMathJax = () => {
        if (window.MathJax && window.MathJax.typesetPromise) {
          resolve()
        } else {
          setTimeout(checkMathJax, 100)
        }
      }
      checkMathJax()
    }
    
    mathjaxScript.onerror = (error) => {
      // 尝试备用CDN
      const backupScript = document.createElement('script')
      backupScript.id = 'MathJax-backup-script'
      backupScript.async = true
      backupScript.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'
      backupScript.onload = () => {
        const checkMathJax = () => {
          if (window.MathJax && window.MathJax.typesetPromise) {
            resolve()
          } else {
            setTimeout(checkMathJax, 100)
          }
        }
        checkMathJax()
      }
      backupScript.onerror = (backupError) => {
        resolve() // 即使失败也要resolve，避免阻塞
      }
      document.head.appendChild(backupScript)
    }
    
    document.head.appendChild(mathjaxScript)
  })
}

// 组件挂载后聚焦输入框
onMounted(async () => {
  const savedUserInfo = localStorage.getItem('userInfo')
  if (savedUserInfo) {
    try {
      userInfo.value = JSON.parse(savedUserInfo)
    } catch (error) {
      console.error('解析用户信息失败:', error)
    }
  }
  
  // 检查用户是否已登录，如果未登录则跳转到登录页
  if (!userInfo.value.isLoggedIn) {
    router.replace('/auth')
    return
  }
  
  // 获取对话历史列表（会自动获取第一个对话的消息历史）
  await fetchChatHistory()
  
  if (inputRef.value) {
    inputRef.value.focus()
  }
  
  // 加载MathJax
  await loadMathJax()
})

// 组件卸载时清理事件监听器
onUnmounted(() => {
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
  document.body.classList.remove('resizing', 'chat-resizing')
  
  // 清理右键菜单相关的事件监听器
  document.removeEventListener('click', closeUserMenu)
  
  // 清理abortController
  if (window.currentAbortController) {
    window.currentAbortController.abort()
    window.currentAbortController = undefined
  }
})
</script>

<style scoped>
.app-container {
  display: grid;
  grid-template-columns: v-bind(historyWidth + 'px') 1fr v-bind(fileWidth + 'px');
  height: 100vh;
  background: #ffffff;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  color: #000000;
}

/* 侧边栏通用样式 */
.sidebar {
  background: #ffffff;
  border-right: 1px solid #e5e5e5;
  border-left: 1px  solid #e5e5e5;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

/* 拖拽手柄样式 */
.resize-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 4px;
  background: transparent;
  cursor: col-resize;
  transition: background-color 0.2s ease;
  z-index: 10;
}

.resize-handle:hover {
  background: #000000;
}

.resize-handle:active {
  background: #000000;
}

.history-resize-handle {
  right: -2px;
}

.file-resize-handle {
  left: -2px;
}

.chat-resize-handle {
  top: -2px;
  left: 0;
  right: 0;
  height: 4px;
  width: auto;
  cursor: row-resize;
}

/* 拖拽时的全局样式 */
.resizing {
  cursor: col-resize !important;
  user-select: none;
}

.resizing * {
  cursor: col-resize !important;
  user-select: none;
}

.resizing.chat-resizing {
  cursor: row-resize !important;
}

.resizing.chat-resizing * {
  cursor: row-resize !important;
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  border-bottom: 1px solid #e5e5e5;
  background: #fafafa;
}

.sidebar-header h3 {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 400;
  color: #000000;
}

.header-buttons {
  display: flex;
  gap: 0.5rem;
}

.clear-selection-btn {
  background: none;
  border: none;
  color: #666666;
  padding: 0.25rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.clear-selection-btn:hover {
  background: #e5e5e5;
  color: #000000;
}

.clear-btn, .upload-btn {
  background: none;
  border: none;
  color: #666666;
  padding: 0.25rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.clear-btn:hover, .upload-btn:hover {
  background: #e5e5e5;
  color: #000000;
}

/* 历史记录侧边栏 */
.history-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem;
}

.history-item {
  padding: 0.75rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom: 0.25rem;
  background: #ffffff;
  border: 1px solid transparent;
}

.history-item:hover {
  background: #fafafa;
  border-color: #e5e5e5;
}

.history-item.active {
  background: #f0f0f0;
  border-color: #000000;
  color: #000000;
}

/* 当前对话样式 - 不可点击 */
.history-item.current-session {
  cursor: default;
  opacity: 0.7;
  position: relative;
}

.history-item.current-session:hover {
  background: #f0f0f0;
  border-color: #000000;
}

.history-item.current-session::after {
  content: "当前";
  position: absolute;
  top: 0.25rem;
  right: 0.5rem;
  font-size: 0.625rem;
  color: #666666;
  background: #e5e5e5;
  padding: 0.125rem 0.25rem;
  border-radius: 2px;
}

.history-title {
  font-size: 0.875rem;
  font-weight: 400;
  margin-bottom: 0.25rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #000000;
}

.history-time {
  font-size: 0.75rem;
  color: #999999;
}

.new-chat-btn {
  width: 100%;
  padding: 0.75rem;
  background: #ffffff;
  border: 1px dashed #e5e5e5;
  border-radius: 4px;
  color: #666666;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  margin-bottom: 0.5rem;
}

.new-chat-btn:hover {
  background: #fafafa;
  border-color: #000000;
  color: #000000;
}

/* 历史记录加载状态 */
.history-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  color: #666666;
  gap: 1rem;
}

.loading-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid #e5e5e5;
  border-top: 2px solid #000000;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 消息加载状态 */
.messages-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  color: #666666;
  gap: 1rem;
  min-height: 200px;
}

/* 主聊天区域 */
.chat-main {
  display: flex;
  flex-direction: column;
  background: #ffffff;
  height: 100vh;
  overflow: hidden;
}

.chat-header {
  padding: 1.05rem 1.5rem;
  flex-shrink: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.home-btn {
  background: none;
  border: none;
  color: #666666;
  padding: 0.5rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.home-btn:hover {
  background: #e5e5e5;
  color: #000000;
}

.chat-header h2 {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 400;
  color: #000000;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-height: 0;
}

.message {
  display: flex;
  gap: 0.75rem;
  max-width: 80%;
  animation: fadeIn 0.3s ease-in;
}

.message.user {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.message.assistant {
  align-self: flex-start;
}

.message-avatar {
  flex-shrink: 0;
}

.user-avatar, .ai-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
}

.user-avatar {
  background: #000000;
  color: #ffffff;
}

.ai-avatar {
  background: #666666;
  color: #ffffff;
}

.ai-avatar svg {
  width: 20px;
  height: 20px;
  color: #ffffff;
}

.message-content {
  background: #fafafa;
  padding: 0.75rem 1rem;
  border-radius: 4px;
  position: relative;
  border: 1px solid #e5e5e5;
}

.message.user .message-content {
  background: #000000;
  color: #ffffff;
  border-color: #000000;
}

.message-text {
  line-height: 1.5;
  word-wrap: break-word;
  font-size: 0.875rem;
}

/* 消息中的大标题样式 */
.message-text .message-title-large {
  color: #000000;
  font-weight: 800;
  font-size: 1.25rem;
  margin: 1rem 0 0.75rem 0;
  padding: 0;
  line-height: 1.3;
  border-bottom: 2px solid #000000;
  padding-bottom: 0.25rem;
}

.message-text .message-title-large:first-child {
  margin-top: 0;
}

/* 消息中的小标题样式 */
.message-text .message-title-small {
  color: #000000;
  font-weight: 700;
  font-size: 1rem;
  margin: 0;
  padding: 0;
  line-height: inherit;
}

/* 消息中的分割线样式 */
.message-text .message-divider {
  border: none;
  height: 1px;
  background: #e5e5e5;
  margin: 1rem 0;
  opacity: 0.6;
}

/* 消息中的圆点列表样式 */
.message-text .message-list-item {
  list-style: none;
  position: relative;
  padding-left: 1.5rem;
  margin: 0.5rem 0;
  line-height: 1.5;
}

.message-text .message-list-item::before {
  content: "•";
  position: absolute;
  left: 0;
  color: #666666;
  font-weight: bold;
  font-size: 1.2em;
}

/* MathJax样式调整 */
.message-text .MathJax {
  font-size: 1em !important;
}

.message-text .MathJax_Display {
  margin: 1rem 0 !important;
  text-align: center;
}

/* 确保数学公式在消息中正确显示 */
.message-text .MathJax_Display .MathJax {
  display: inline-block !important;
}

/* 流式更新时隐藏原始数学公式 */
.message-text .math-formula-raw {
  display: none;
}

.message-time {
  font-size: 0.75rem;
  opacity: 0.7;
  margin-top: 0.5rem;
}

.input-container {
  padding: 0.5rem 1rem;
  position: relative;
  flex-shrink: 0;
  background: #ffffff;
  border-top: 1px solid #e5e5e5;
}

.input-wrapper {
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: 4px;
  padding: 0.25rem;
  padding-right: 3rem;
  transition: border-color 0.2s ease;
}

.input-wrapper:focus-within {
  border-color: #000000;
}

.message-input {
  width: 100%;
  border: none;
  outline: none;
  padding: 0.25rem;
  font-size: 1rem;
  resize: none;
  min-height: 24px;
  font-family: inherit;
  background: transparent;
  color: #000000;
}

.message-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.message-input::placeholder {
  color: #999999;
}

.send-btn {
  position: absolute;
  bottom: 0.75rem;
  right: 1.75rem;
  background: #000000;
  border: 1px solid #000000;
  border-radius: 10%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #ffffff;
  z-index: 10;
}

.send-btn:hover:not(:disabled) {
  background: #333333;
  transform: scale(1.05);
}

.send-btn:disabled {
  background: #cccccc;
  border-color: #cccccc;
  color: #999999;
  cursor: not-allowed;
  transform: none;
}

.loading-dots {
  display: flex;
  gap: 4px;
  padding: 0.5rem 0;
}

.loading-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #666666;
  animation: bounce 1.4s ease-in-out infinite both;
}

.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }

/* 文件侧边栏 */
.file-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem;
}

.file-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom: 0.25rem;
  background: #ffffff !important;
  border: 1px solid transparent;
  user-select: none;
}

.file-item * {
  background: transparent !important;
}

.file-item:hover {
  background: #fafafa !important;
  border-color: #e5e5e5;
}

.file-item:hover * {
  background: transparent !important;
}

.file-item.selected {
  background: #f0f0f0 !important;
  border-color: #000000;
}

.file-item.selected * {
  background: transparent !important;
}

.file-checkbox {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  cursor: pointer;
}

.checkbox-input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: #000000;
  margin: 0;
}

.file-icon {
  color: #666666;
  flex-shrink: 0;
}

.file-info {
  flex: 1;
  min-width: 0;
  background: transparent;
}

.file-name {
  font-size: 0.875rem;
  font-weight: 400;
  color: #000000;
  background: transparent;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-bottom: 0.25rem;
  user-select: none;
}

.file-name::selection {
  background: #e5e5e5;
  color: #000000;
}

.file-name::-moz-selection {
  background: #e5e5e5;
  color: #000000;
}

.file-size {
  font-size: 0.75rem;
  color: #999999;
  background: transparent;
  user-select: none;
}

.file-size::selection {
  background: #e5e5e5;
  color: #000000;
}

.file-size::-moz-selection {
  background: #e5e5e5;
  color: #000000;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  text-align: center;
  color: #666666;
}

.empty-state svg {
  margin-bottom: 1rem;
  opacity: 0.5;
}

.empty-state p {
  margin: 0 0 1rem 0;
  font-size: 0.875rem;
}

.upload-file-btn {
  background: #000000;
  color: #ffffff;
  border: 1px solid #000000;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.2s ease;
}

.upload-file-btn:hover {
  background: #333333;
}

/* 弹窗样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  width: 90%;
  max-width: 400px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid #e5e5e5;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #e5e5e5;
  background: #fafafa;
}

.modal-header h3 {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 400;
  color: #000000;
}

.modal-close {
  background: none;
  border: none;
  color: #666666;
  padding: 0.25rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.modal-close:hover {
  background: #e5e5e5;
  color: #000000;
}

.modal-body {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  text-align: center;
}

.modal-icon {
  color: #666666;
  font-size: 48px;
  margin-bottom: 0.5rem;
}

.modal-body p {
  margin: 0 0 0.5rem 0;
  font-size: 0.875rem;
  color: #666666;
}

.modal-warning {
  font-size: 0.75rem;
  color: #999999;
  margin-top: 0.25rem;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  padding: 1rem 1.5rem;
  border-top: 1px solid #e5e5e5;
  background: #fafafa;
}

.modal-btn {
  padding: 0.5rem 1rem;
  border-radius: 4px;
  border: 1px solid;
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 400;
  transition: all 0.2s ease;
}

.modal-btn.cancel-btn {
  background: #ffffff;
  color: #666666;
  border-color: #e5e5e5;
  margin-right: 0.5rem;
}

.modal-btn.cancel-btn:hover {
  background: #fafafa;
  color: #000000;
  border-color: #000000;
}

.modal-btn.confirm-btn {
  background: #000000;
  color: #ffffff;
  border-color: #000000;
}

.modal-btn.confirm-btn:hover {
  background: #333333;
}

/* 文件预览弹窗样式 */
.file-modal {
  max-width: 600px;
  max-height: 80vh;
}

.file-preview-body {
  padding: 0;
  gap: 0;
  align-items: stretch;
}

.file-info {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.5rem;
  border-bottom: 1px solid #e5e5e5;
  background: #fafafa;
}

.file-icon {
  color: #666666;
  flex-shrink: 0;
}

.file-details h4 {
  margin: 0 0 0.25rem 0;
  font-size: 1rem;
  font-weight: 400;
  color: #000000;
}

.file-details p {
  margin: 0;
  font-size: 0.875rem;
  color: #999999;
}

.file-content {
  flex: 1;
  padding: 1.5rem;
  max-height: 400px;
  overflow-y: auto;
  background: #fafafa;
}

.file-content pre {
  margin: 0;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 0.875rem;
  line-height: 1.5;
  color: #000000;
  white-space: pre-wrap;
  word-wrap: break-word;
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 滚动条样式 */
.history-list::-webkit-scrollbar,
.messages-container::-webkit-scrollbar,
.file-list::-webkit-scrollbar {
  width: 4px;
}

.history-list::-webkit-scrollbar-track,
.messages-container::-webkit-scrollbar-track,
.file-list::-webkit-scrollbar-track {
  background: transparent;
}

.history-list::-webkit-scrollbar-thumb,
.messages-container::-webkit-scrollbar-thumb,
.file-list::-webkit-scrollbar-thumb {
  background: #e5e5e5;
  border-radius: 2px;
}

.history-list::-webkit-scrollbar-thumb:hover,
.messages-container::-webkit-scrollbar-thumb:hover,
.file-list::-webkit-scrollbar-thumb:hover {
  background: #cccccc;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .app-container {
    grid-template-columns: 240px 1fr 240px;
  }
  
  .history-sidebar {
    width: 240px !important;
  }
  
  .file-sidebar {
    width: 240px !important;
  }
}

@media (max-width: 768px) {
  .app-container {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
  }
  
  .sidebar {
    display: none;
  }
  
  .chat-main {
    grid-row: 1 / -1;
  }
  
  .resize-handle {
    display: none;
  }
  

}

/* 用户账号区域 */
.user-account-section {
  padding: 1rem;
  border-top: 1px solid #e5e5e5;
  background: #fafafa;
  flex-shrink: 0;
  position: relative; /* Added for user context menu positioning */
}

.user-info {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
  padding: 0.5rem;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.user-info:hover {
  background: #e5e5e5;
}

.user-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000000;
  color: #ffffff;
  font-weight: 600;
  font-size: 1rem;
  flex-shrink: 0;
}

.avatar-image {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #000000;
  color: #ffffff;
  font-weight: 600;
  font-size: 1rem;
}

.avatar-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #666666;
  color: #ffffff;
}

.user-details {
  flex: 1;
  min-width: 0;
}

.user-nickname {
  font-size: 0.875rem;
  font-weight: 500;
  color: #000000;
  margin-bottom: 0.25rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-status {
  font-size: 0.75rem;
  color: #666666;
}

/* 用户右键菜单样式 */
.user-context-menu {
  position: fixed;
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  z-index: 1001;
  padding: 0.5rem 0;
  min-width: 140px;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #000000;
  font-size: 0.875rem;
  font-weight: 400;
}

.menu-item:hover {
  background: #f0f0f0;
  color: #000000;
}

.menu-item:active {
  background: #e5e5e5;
}

.menu-item svg {
  color: #666666;
  flex-shrink: 0;
  transition: color 0.2s ease;
}

.menu-item:hover svg {
  color: #000000;
}

/* 消息中的链接样式 */
.message-text .message-link {
  color: #1e3a8a !important;
  font-weight: bold !important;
  text-decoration: none !important;
  transition: all 0.2s ease;
}
.message-text .message-link:hover {
  color: #1e40af !important;
  text-decoration: none !important;
}
.message-text .message-link:visited {
  color: #3730a3 !important;
}

</style> 